// Copyright (C) Kumo inc. and its affiliates.
// Author: Jeff.li lijippy@163.com
// All rights reserved.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published
// by the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program.  If not, see <https://www.gnu.org/licenses/>.
//


#pragma once

#include <pollux/expression/cast_hooks.h>
#include <pollux/expression/eval_ctx.h>

namespace kumo::pollux::exec {
    // This class provides cast hooks following Presto semantics.
    class PrestoCastHooks : public CastHooks {
    public:
        explicit PrestoCastHooks(const core::QueryConfig &config);

        // Uses the default implementation of 'castFromDateString'.
        Expected<Timestamp> castStringToTimestamp(
            const StringView &view) const override;

        Expected<Timestamp> castIntToTimestamp(int64_t seconds) const override;

        Expected<std::optional<Timestamp> > castDoubleToTimestamp(
            double seconds) const override;

        // Uses standard cast mode to cast from string to date.
        Expected<int32_t> castStringToDate(
            const StringView &dateString) const override;

        // Allows casting 'NaN', 'Infinity', and '-Infinity' to real, but not 'Inf' or
        // these strings with different letter cases.
        Expected<float> castStringToReal(const StringView &data) const override;

        // Allows casting 'NaN', 'Infinity', and '-Infinity' to double, but not 'Inf'
        // or these strings with different letter cases.
        Expected<double> castStringToDouble(const StringView &data) const override;

        // Returns the input as is.
        StringView removeWhiteSpaces(const StringView &view) const override;

        // Returns cast options following 'isLegacyCast' and session timezone.
        const TimestampToStringOptions &timestampToStringOptions() const override;

        bool truncate() const override {
            return false;
        }

        PolicyType getPolicy() const override;

    private:
        const bool legacyCast_;
        TimestampToStringOptions options_ = {
            .precision = TimestampToStringOptions::Precision::kMilliseconds
        };
    };
} // namespace kumo::pollux::exec
